/**
 * 获取随机数组
 * @param start 开始的范围
 * @param end  结束的范围
 * @param count 多少个
 */
export const randomArr = (start: number = 0, end: number = 20, count: number = 8) => {
    const arr: number[] = []
    for (let i = 0; i < count; i++) {
        arr.push(random(start, end))
    }
    return arr;
}

/**
 * 随机获取一个有序数组
 * @param count 
 */
export const getSortedArr = (count = 10) => {
    // 随机生成一个数字
    const s = random(1, count),
        e = s + count,
        arr = [];

    for (let i = s; i < e; i++) {
        arr.push(i)
    }
    return arr;
}


/**
 * 尾部部分已拍好序数组
 * @param total 数组总数量
 * @param count 尾部已排好序的数量
 */
export const endSorted = (total = 1000, count = 100) => {
    if (total < count) return [];
    const arr = []
    let i = 0;
    for (; i < total - count; i++) {
        arr.push(random(0, 100000))
    }
    i = 0

    arr.push(...getSortedArr(count))
    return arr;
}

/**
 * 首部部分已排好序数组
 * @param total 数组总数量
 * @param count 首部已排好序的数量
 */
export const startSorted = (total = 1000, count = 100) => {
    if (total < count) return [];
    const arr = []
    let i = 0;
    arr.push(...getSortedArr(count))
    for (; i < total - count; i++) {
        arr.push(random(0, 100000))
    }
    i = 0

    return arr;
}

/**
 * 判断数组是否已经排好序了
 * @param arr 
 */
export const isSorted = (arr: number[]) => {
    const len = arr.length;
    if (len <= 1) return true;

    for (let i = 0; i < len; i++) {
        // 只要比下一个大，就不是拍好序的
        if (arr[i] - arr[i + 1] > 0) {
            return false
        }
    }
    // 走完了没有有比下一个大的，说明是有序的
    return true
}

/**
 * 获取倒序的数组
 * @param count 
 */
export const getReverseArr = (count: number) => {
    const arr: number[] = [];
    for (let i = 0; i < count; i++) {
        arr.push(random(1, 10000))
    }
    return arr;
}


/**
 * 获取start-end范围内的数组
 * @param start 
 * @param end 
 * 
 * e.g:  start: 5, end: 10
 * floor (5, 11) => [5, 10]
 */
export const random = (start: number, end: number) => {
    return Math.floor((Math.random() * (end - start + 1) + start))
}

/**
 * 校验数组
 * @param arr 
 */
export const checkArr = (arr: number[]) => arr.length <= 1


/**
 * 二分查找
 * @param arr 
 */
export const binarySearch = (arr: number[], ele: number) => {
    // 校验数组
    if (checkArr(arr)) return arr;

    const compare = (l: number, r: number) => l - r

    // 起始和结束索引
    let s = 0,
        e = arr.length - 1;

    while (s <= e) {
        // 获取中间位置的元素
        let half = (s + e) >> 1;
        const cmp = compare(arr[half], ele);

        if (cmp > 0) {
            // 中间元素大于所找的元素，往前
            e = half - 1

        } else if (cmp < 0) {
            // 中间元素小于所找的元素，往后找
            s = half + 1
        } else {
            // 返回索引
            return half
        }
    }

    // return 0
}
